#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "cmd.h"

void exec_cmd(struct cmd *cmd)
{
	pid_t pid = fork();
	int a = strcmp(cmd->argv[0],"cd");
	int b = strcmp(cmd->argv[0],"pwd");
	int c = strcmp(cmd->argv[0],"exit");

	if(pid == 0) {
		//printf("%s\n",cmd->argv[0]);
		if(a != 0 && b != 0 && c != 0) {
			//printf("%s\n",cmd->argv[0]);
			if(cmd->output != NULL) {
				char *path = malloc(sizeof(cmd->output) - 1);
				strcpy(path,strtok(cmd->output,">"));
				int fd = open(path , O_WRONLY | O_TRUNC | O_CREAT , 0666);
				dup2(fd,1);
				close(fd);
			}
			if(cmd->input != NULL) {
				char *path = malloc(sizeof(cmd->input) - 1);
				strcpy(path,strtok(cmd->input,"<"));
				int fd = open(path , O_RDONLY);
				dup2(fd,0);
				close(fd);
			}
			int error = execvp(cmd->argv[0],cmd->argv);
			exit(127);
		}
		exit(0);
	}
	else {
		int status;
		wait(&status);
		if(!(WIFEXITED(status))) exit(-1);

		if(a == 0) chdir(cmd->argv[1]);
		if(b == 0) {
			char path[128];
			bzero(path,sizeof(path));
			getcwd(path,sizeof(path));
			write(1,path,sizeof(path));
			write(1,"\n",2);
		}
		if(c == 0) exit(0);
	}
}

int builtin_cmd(struct cmd *cmd)
{
}

void exec_pipe_cmd(int cmdc, struct cmd *cmdv)
{
	/*if(cmdc == 1) exec_cmd(cmdv + 0);
	else {	
		int temp0 = dup(0);
		int temp1 = dup(1);
	
		int fd[2];
		pipe(fd);
		//dup2(fd[1],1);
		
		int flag0 = fcntl(fd[0] , F_GETFL);
		flag0 |= O_NONBLOCK;
		fcntl(fd[0] , F_SETFL , flag0);
		int flag1 = fcntl(fd[1] , F_GETFL);
		flag1 |= O_NONBLOCK;
		fcntl(fd[1] , F_SETFL , flag1);

		int i;
		for(i = 0 ; i < cmdc ; i++) {
			dup2(fd[1],1);
			if(i == cmdc - 1) dup2(temp1,1);
			if(i > 0 ) dup2(fd[0],0);
			struct cmd *cmd = cmdv + i;
			exec_cmd(cmd);
		}
		dup2(temp0,0);
		close(fd[0]);
		close(fd[1]);
	}*/

	if(cmdc == 1) {
		exec_cmd(cmdv + 0);
		exit(0);
	}

	int fd[2];
	pipe(fd);
	pid_t pid = fork();

	int temp0 = dup(0);

	if(pid == 0) {
		dup2(fd[1],1);
		close(fd[0]);
		close(fd[1]);
		exec_pipe_cmd(cmdc - 1 , cmdv);
		exit(0);   //really important
	}

	else {
		int status;
		wait(&status);
		if(!(WIFEXITED(status))) exit(-1);

		dup2(fd[0],0);
		close(fd[0]);
		close(fd[1]);
		exec_cmd(cmdv + cmdc - 1);
		dup2(temp0,0);  //really important
	}
}
